<template>
	<div>
		<el-dialog title="多实例配置" width="600px" draggable v-bind="$attrs">
			<el-descriptions :column="1" size="mini" border>
				<el-descriptions-item label="使用说明">按照BPMN2.0规范的要求，用于为每个实例创建执行的父执行，会提供下列变量:</el-descriptions-item>
				<el-descriptions-item label="nrOfInstances">实例总数。</el-descriptions-item>
				<el-descriptions-item label="nrOfActiveInstances">当前活动的（即未完成的），实例数量。对于顺序多实例，这个值总为1。</el-descriptions-item>
				<el-descriptions-item label="nrOfCompletedInstances">已完成的实例数量。</el-descriptions-item>
				<el-descriptions-item label="loopCounter">给定实例在for-each循环中的index。</el-descriptions-item>
			</el-descriptions>

			<my-form ref="refForm" :model="formData" :formItem="formItem" label-width="80" class="m-t-10" />
			<template #footer>
				<my-button
					@click.prevent="
						() => {
							formData.value = {};
							$attrs['onUpdate:modelValue'](false);
						}
					"
					>取 消</my-button
				>
				<el-button type="primary" @click.prevent="() => closeDialog().then(() => $attrs['onUpdate:modelValue'](false))">确 定</el-button>
			</template>
		</el-dialog>
	</div>
</template>

<script setup>
import { formatJsonKeyValue } from '../../common/parseElement';
import hooksPanel, { PanelProps } from '../../common/Panel';

const formItem = [
	{
		prop: 'collection',
		label: '集合',
		description:
			'collection: 属性会作为表达式进行解析。如果表达式解析为字符串而不是一个集合，<br />不论是因为本身配置的就是静态字符串值，还是表达式计算结果为字符串，<br />这个字符串都会被当做变量名，并从流程变量中用于获取实际的集合。'
	},
	{
		prop: 'elementVariable',
		label: '元素变量',
		description:
			'elementVariable: 每创建一个用户任务前，先以该元素变量为label，集合中的一项为value，<br />创建（局部）流程变量，该局部流程变量被用于指派用户任务。<br />一般来说，该字符串应与指定人员变量相同。'
	},
	{
		itemType: 'select',
		prop: 'isSequential',
		label: '执行方式',
		description: '并行会签（parallel）、串行会签(sequential)，其中并行会签的意思是 多个人同时执行任务。串行会签是按顺序执行任务。',
		list: [
			{ label: '串行', value: true },
			{ label: '并行', value: false }
		],
		fileType: { label: 'label', value: 'value' }
	},
	{
		prop: 'completionCondition',
		label: '完成条件',
		description:
			'completionCondition: 多实例活动在所有实例都完成时结束，然而也可以指定一个表达式，在每个实例<br />结束时进行计算。当表达式计算为true时，将销毁所有剩余的实例，并结束多实例<br />活动，继续执行流程。例如 ${nrOfCompletedInstances/nrOfInstances >= 0.6 }，<br />表示当任务完成60%时，该节点就算完成'
	}
];

const props = defineProps({
		...PanelProps
	}),
	{ formData, updateProperties } = hooksPanel(props);

onMounted(() => {
	const cache = JSON.parse(JSON.stringify(props.element.businessObject.loopCharacteristics ?? {}));
	cache.completionCondition = cache.completionCondition?.body;
	// 拼接多实例对象
	if (props.element.businessObject.loopCharacteristics) {
		Object.assign(cache, props.element.businessObject.loopCharacteristics.$attrs);
	}
	formData.value = formatJsonKeyValue(cache);
});

function updateElement() {
	if (formData.value.isSequential !== null && formData.value.isSequential !== undefined) {
		let loopCharacteristics = props.element.businessObject.get('loopCharacteristics');
		if (!loopCharacteristics) {
			loopCharacteristics = props.modeler.get('moddle').create('bpmn:MultiInstanceLoopCharacteristics');
		}
		loopCharacteristics['isSequential'] = formData.value.isSequential;
		loopCharacteristics['collection'] = formData.value.collection;
		loopCharacteristics['elementVariable'] = formData.value.elementVariable;

		loopCharacteristics.$attrs['isSequential'] = formData.value.isSequential;
		loopCharacteristics.$attrs['flowable:collection'] = formData.value.collection;
		loopCharacteristics.$attrs['flowable:elementVariable'] = formData.value.elementVariable;

		if (formData.value.completionCondition) {
			loopCharacteristics['completionCondition'] = props.modeler
				.get('moddle')
				.create('bpmn:Expression', { body: formData.value.completionCondition });
		}
		updateProperties({ loopCharacteristics });
	} else {
		delete props.element.businessObject.loopCharacteristics;
	}
}
const refForm = ref(null);
function closeDialog() {
	return refForm.value.$refs.refMyForm
		.validate()
		.then(() => {
			updateElement();
		})
		.catch((e) => console.error(e));
}
</script>
